package math;

import java.util.Iterator;

public class Range implements Iterable<Integer> {

	private int min;
	private int max;
	private boolean inclusiveMin;
	private boolean inclusiveMax;
	
	public int getMin() {
		return min;
	}

	public int getMax() {
		return max;
	}

	public boolean isInclusiveMin() {
		return inclusiveMin;
	}

	public boolean isInclusiveMax() {
		return inclusiveMax;
	}
	
	public int getRandom() {
		return (int)(((max - min - (inclusiveMin ? 0 : 1) - (inclusiveMax ? 0 : 1)) * Math.random()) + min + (inclusiveMin ? 0 : 1));
	}
	
	public boolean included(double i) {
		return (inclusiveMin ? i >= min : i > min) && (inclusiveMax ? i <= max : i < max);
	}
	
	public boolean excluded(double i) {
		return !included(i);
	}

	public Range(int min, int max, boolean inclusiveMin, boolean inclusiveMax) {
		this.min = min;
		this.max = max;
		if (min > max || min == max)
			throw new IllegalArgumentException("MIN must be less than MAX");
		this.inclusiveMin = inclusiveMin;
		this.inclusiveMax = inclusiveMax;
	}
	
	public Range(String range) {
		if (range == null || !range.trim().matches("[\\[(] ?\\d+, ?\\d+ ?[\\])]"))
			throw new IllegalArgumentException();
		range = range.trim();
		String[] arr = range.split(",");
		arr[0] = arr[0].trim();
		arr[1] = arr[1].trim();
		inclusiveMin = arr[0].charAt(0) == '[';
		min = Integer.parseInt(arr[0].substring(1).trim());
		inclusiveMax = arr[1].charAt(arr[1].length()-1) == ']';
		max = Integer.parseInt(arr[1].substring(0,arr[1].length()-1).trim());
		if (min > max || min == max)
			throw new IllegalArgumentException("MIN must be less than MAX");
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder(inclusiveMin ? "[" : "(");
		sb.append(min).append(", ").append(max);
		sb.append(inclusiveMax ? "]" : ")");
		return sb.toString();
	}

	@Override
	public Iterator<Integer> iterator() {
		return new Iterator<Integer>() {
			int index = inclusiveMin ? min : min + 1;
			@Override
			public boolean hasNext() {
				return index < (inclusiveMax ? max + 1 : max);
			}

			@Override
			public Integer next() {
				return index++;
			}

			@Override
			public void remove() {
				// Does nothing
			}
		};
	}
}
